﻿#pragma once
#include <string>
#include <vector>
#include <sstream>
#include <iomanip>
#include <stdexcept>
#include <type_traits>
#include <cmath>
#include "String.h"
#include "Object.h"
#include "ObjectUtil.hpp"
#include "StringBuilder.h"

namespace yzrilyzr_lang{
	class StringFormat{
		public:
		template<typename... Args>
		static String format(const String & format, Args... args){
			std::vector<String> arguments={ObjectUtil::toString(args)...};
			StringBuilder result;
			u_index pos=0;
			u_index argIndex=0;
			u_index len=format.length();

			while(pos < len){
				u_index percentPos=format.indexOf('%', pos);
				if(percentPos < 0){
					result+=format.substring(pos);
					break;
				}

				// 添加%之前的文本
				result+=format.substring(pos, percentPos);

				// 处理%后的格式说明符
				if(percentPos + 1 >= len){
					throw yzrilyzr_lang::FormatException("Incomplete format specifier at end of string");
				}

				// 解析格式说明符
				u_index specifierPos=percentPos + 1;
				char currentChar=format[specifierPos];

				// 处理转义的%%
				if(currentChar == '%'){
					result+='%';
					pos=specifierPos + 1;
					continue;
				}

				// 解析格式宽度、精度和填充字符
				char fillChar=' ';
				int width=0;
				int precision=-1; // -1表示未指定精度
				bool hasWidth=false;
				bool hasPrecision=false;

				// 检查是否有填充字符（通常是0）
				if(specifierPos < len - 1 && format[specifierPos] == '0'){
					fillChar='0';
					specifierPos++;
				}

				// 解析宽度数字
				while(specifierPos < len && format[specifierPos] >= '0' && format[specifierPos] <= '9'){
					width=width * 10 + (format[specifierPos] - '0');
					hasWidth=true;
					specifierPos++;
				}

				// 解析精度（如果有点号）
				if(specifierPos < len && format[specifierPos] == '.'){
					specifierPos++;
					precision=0;
					hasPrecision=true;

					// 解析精度数字
					while(specifierPos < len && format[specifierPos] >= '0' && format[specifierPos] <= '9'){
						precision=precision * 10 + (format[specifierPos] - '0');
						specifierPos++;
					}
				}

				if(specifierPos >= len){
					throw yzrilyzr_lang::FormatException("Incomplete format specifier at end of string");
				}

				char specifier=format[specifierPos];
				pos=specifierPos + 1;

				// 检查参数索引
				if(argIndex >= arguments.size()){
					throw yzrilyzr_lang::FormatException("More format specifiers than arguments");
				}

				// 根据格式说明符处理参数
				switch(specifier){
					case 's': // 字符串
					{
						String strValue=arguments[argIndex];
						if(hasWidth && strValue.length() < width){
							// 对于字符串，只在左侧填充空格
							String padded(fillChar == '0'?' ':fillChar);
							padded*=(width - strValue.length());
							result+=padded + strValue;
						} else{
							result+=strValue;
						}
					}
					break;
					case 'd': // 整数
					case 'o': // 八进制
					case 'x': // 十六进制
					case 'X': // 大写十六进制
						try{
							int value=std::stoi(arguments[argIndex].tostring());
							std::ostringstream oss;

							// 设置填充字符和宽度
							if(hasWidth){
								oss << std::setfill(fillChar) << std::setw(width);
							}

							// 设置数值格式
							if(specifier == 'd') oss << value;
							else if(specifier == 'o'){
								oss << std::oct;
								if(hasWidth) oss << std::setfill(fillChar) << std::setw(width);
								oss << value;
							} else if(specifier == 'x'){
								oss << std::hex << std::nouppercase;
								if(hasWidth) oss << std::setfill(fillChar) << std::setw(width);
								oss << value;
							} else if(specifier == 'X'){
								oss << std::hex << std::uppercase;
								if(hasWidth) oss << std::setfill(fillChar) << std::setw(width);
								oss << value;
							}
							result+=oss.str();
						} catch(...){
							throw yzrilyzr_lang::FormatException(yzrilyzr_lang::String("Invalid integer format for argument: ") + arguments[argIndex]);
						}
						break;
					case 'f': // 浮点数
					case 'e': // 科学计数法
					case 'E': // 大写科学计数法
					case 'g': // 通用格式
					case 'G': // 大写通用格式
						try{
							double value=std::stod(arguments[argIndex].tostring());
							std::ostringstream oss;

							// 设置精度
							if(hasPrecision){
								oss << std::setprecision(precision);
							} else{
								oss << std::setprecision(6); // 默认精度
							}

							// 设置宽度（浮点数通常不使用0填充）
							if(hasWidth && fillChar == ' '){
								oss << std::setw(width);
							}

							if(specifier == 'f') oss << std::fixed << value;
							else if(specifier == 'e') oss << std::scientific << std::nouppercase << value;
							else if(specifier == 'E') oss << std::scientific << std::uppercase << value;
							else if(specifier == 'g') oss << std::defaultfloat << std::nouppercase << value;
							else if(specifier == 'G') oss << std::defaultfloat << std::uppercase << value;

							result+=oss.str();
						} catch(...){
							throw yzrilyzr_lang::FormatException(yzrilyzr_lang::String("Invalid float format for argument: ") + arguments[argIndex]);
						}
						break;
					case 'b': // 布尔值
						result+=(arguments[argIndex] == "true" || arguments[argIndex] == "1")?"true":"false";
						break;
					case 'c': // 字符
						if(arguments[argIndex].length() != 1){
							throw yzrilyzr_lang::FormatException("Expected single character for %c format");
						}
						result+=arguments[argIndex][0];
						break;
					default:
						throw yzrilyzr_lang::FormatException(String("Unknown format specifier: %") + specifier);
				}

				argIndex++;
			}

			if(argIndex < arguments.size()){
				throw yzrilyzr_lang::FormatException("More arguments than format specifiers");
			}

			return result;
		}
		template<typename... Args>
		static String object2string(const String className, Args... args){
			std::vector<String> arguments={ObjectUtil::toString(args)...};
			std::stringstream ss;
			ss << "std::make_shared<" << className << ">(\n";
			u_index i=0;
			for(auto a : arguments){
				ss << "\t" << a;
				i++;
				if(i < arguments.size())ss << ", \n";
			}
			ss << "\n)";
			return ss.str();
		}
	};
}